package com.flyqiu.flow.core.manage;


import com.flyqiu.common.tools.FlyQiuCollectionTools;
import com.flyqiu.flow.api.cache.FlyQiuFlowCache;
import com.flyqiu.flow.api.cache.FlyQiuFlowCacheManage;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class DefaultFlyQiuFlowCacheManage implements FlyQiuFlowCacheManage {

    private final List<FlyQiuFlowCache> localCache;


    public DefaultFlyQiuFlowCacheManage() {
        localCache = new ArrayList<>();
    }


    /**
     * 注册缓存器
     *
     * @param cache 缓存器
     */
    @Override
    public void registerCache(FlyQiuFlowCache cache) {
        if (localCache.contains(cache)) return;
        localCache.add(cache);
        sortCache();
    }

    @Override
    public void unRegisterCache(FlyQiuFlowCache cache) {
        if (localCache.contains(cache)) return;
        localCache.remove(cache);
        sortCache();
    }

    @Override
    public List<FlyQiuFlowCache> getCaches() {
        return new ArrayList<>(localCache);
    }

    private void sortCache() {
        localCache.sort((o1, o2) -> {
            int level1 = o1.cacheLevel();
            int level2 = o2.cacheLevel();
            if (level1 == level2) {
                return 0;
            }
            return level1 - level2;
        });
    }

    /**
     * 获取缓存数据
     *
     * @param key 数据key
     * @return 缓存的数据
     */
    public Object getCacheData(String key) {
        return FlyQiuCollectionTools.find(localCache, cache -> {
            if (!cache.hasKey(key)) {
                return null;
            }
            return cache.getData(key);
        });
    }

    /**
     * 获取缓存数据并转换未指定类型对象
     *
     * @param key 数据key
     * @param <T> 转换后的类型
     * @return 数据
     */
    @SuppressWarnings("unchecked")
    public <T> T getCacheDataToObject(String key, Class<T> clazz) {
        List<T> list = FlyQiuCollectionTools.find(localCache, cache -> {
            if (!cache.hasKey(key)) {
                return null;
            }
            return cache.getData(key, clazz);
        });
        if (list.isEmpty()) return null;
        return list.get(0);
    }

    /**
     * 缓存数据延时
     *
     * @param key    数据key
     * @param expire 过期时间
     */
    public void delayed(String key, long expire, TimeUnit unit) {
        expire = unit.toMillis(expire);
        delayed(key, expire);
    }

    /**
     * 缓存数据延时
     *
     * @param key    数据key
     * @param expire 过期时间
     */
    public void delayed(String key, long expire) {
        FlyQiuCollectionTools.iterator(localCache, cache -> {
            cache.delayed(key, expire);
        });

    }

    /**
     * 缓存数据
     *
     * @param key    数据key
     * @param data   数据
     * @param expire 过期时间
     * @param unit   时间单位
     */

    public void putData(String key, Object data, long expire, TimeUnit unit) {
        expire = unit.toMillis(expire);
        putData(key, data, expire);
    }

    /**
     * 缓存数据
     *
     * @param key    数据key
     * @param data   数据
     * @param expire 过期时间
     */
    public void putData(String key, Object data, long expire) {
        if (localCache.isEmpty()) {
            return;
        }
        FlyQiuFlowCache cache = localCache.get(0);
        cache.putData(key, data, expire);
    }
}
